/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138;

import java.io.*;
import java.net.URL;
import java.security.*;
import java.sql.Connection;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.Node;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import sun.misc.*;

/**
 *
 * @author Vasa
 */
public class SettingsImpl implements Settings{

    private String username = "";
    private String password = "";
    private String dictionaryName = "";
    
    private final byte[] keyValue = new byte[]{'k','E','y','f','o','R','A','E','S',
                                                'e','n','c','a','D','e','C'};
    
    private Document doc;
    
    public SettingsImpl()
    {
        try
        {
            loadFromXML();
        }catch(Exception ex)
        {
            username = "";
            password = "";
            dictionaryName = "ssjc";
        }
    }
    
    @Override
    public String getUsername()
    {
        return this.username;
    }
    
    @Override
    public void setUsername(String username)
    {
        this.username = username;
        
    }
    
    @Override
    public String getPassword()
    {
        return this.password;
    }
    
    @Override
    public void setPassword(String password)
    {
        this.password = password;
    }
    
    @Override
    public String getDictionaryName()
    {
        return this.dictionaryName;
    }
    
    @Override
    public void setDictionaryName(String dictionaryName)
    {
        this.dictionaryName = dictionaryName;
    }
    
    @Override
    public void saveToXML() throws ParserConfigurationException,
            IOException, TransformerException
    {
        //soubor - nastaveni cesty
        String str;
        if(new File(parsePath(System.getProperty("user.home")) + "/Documents/SettingsDEBDict").exists())
        {
            str = parsePath(System.getProperty("user.home")) + "/Documents/SettingsDEBDict/settings.xml";
        }
        else
        {
            new File(parsePath(System.getProperty("user.home")) + "/Documents/SettingsDEBDict").mkdir();
            str = parsePath(System.getProperty("user.home")) + "/Documents/SettingsDEBDict/settings.xml";
        }
        //String str = "C:/Users/Vasa/Documents/SettingsDEBDict/settings.xml";
        
        File f = new File(str);
        if(!f.exists())f.createNewFile();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        doc = builder.newDocument();
        
        
        //telo xml
        Element rootElement = doc.createElement("setting");
        doc.appendChild(rootElement);
        
        Element dict = doc.createElement("dictionary");
        dict.appendChild(doc.createTextNode(dictionaryName));
        rootElement.appendChild(dict);
        
        Element user = doc.createElement("username");
        user.appendChild(doc.createTextNode(username));
        rootElement.appendChild(user);
        
        Element pass = doc.createElement("password");
        try
        {
            pass.appendChild(doc.createTextNode(encryptPassword()));
        }
        catch(Exception ex){
 	    pass.appendChild(doc.createTextNode(""));
	}
        rootElement.appendChild(pass);
        
        
        //zapsani xml do dokumentu
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        DOMSource source = new DOMSource(doc);
        FileWriter fileWriter = new FileWriter(f);
        BufferedWriter writer = new BufferedWriter(fileWriter);
        StreamResult result =  new StreamResult(writer);
        transformer.transform(source, result);
        writer.close();
        fileWriter.close();
    }
    
    private String parsePath(String path)
    {
        String[] parsed = path.split("\\\\");
        String str = "";
        for(int i = 0; i < parsed.length; i++)
        {
            if(i!=0)
            {
                str += "/" + parsed[i];
            }
            else
                str += parsed[i];
        }
        return str;
    }
    
    public void loadFromXML()throws ParserConfigurationException, SAXException,
            IOException
    {
        String str = parsePath(System.getProperty("user.home")) + "/Documents/SettingsDEBDict/settings.xml";
        File f = new File(str);
        //"C:/Users/Vasa/Documents/SettingsDEBDict/settings.xml"
        if(!f.exists())
        {
            username = "";
            password = "";
            dictionaryName = "ssjc";
            return;
        }
        
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        doc = builder.parse(f);
        doc.getDocumentElement ().normalize();
            
        NodeList dictionary = doc.getElementsByTagName("dictionary");
        NodeList nl = dictionary.item(0).getChildNodes();
        this.dictionaryName = nl.item(0).getNodeValue();
        if(this.dictionaryName == null) this.dictionaryName = "";

        NodeList username = doc.getElementsByTagName("username");
        nl = username.item(0).getChildNodes();
        this.username = nl.item(0).getNodeValue();
        if(this.username == null) this.username = "";

        NodeList password = doc.getElementsByTagName("password");
        nl = password.item(0).getChildNodes();
        try
        {
            this.password = decryptPassword(nl.item(0).getNodeValue());
        }catch(Exception ex){}
        if(this.password == null) this.password = "";
    }
    
    private String encryptPassword() throws Exception
    {
        Key key = generateKey();
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encValue = c.doFinal(password.getBytes());
        return new BASE64Encoder().encode(encValue);
    }
    
    private String decryptPassword(String encryptedPassword)throws Exception
    {
        Key key = generateKey();
        Cipher c = Cipher.getInstance("AES");
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedPassword);
        byte[] decValue = c.doFinal(decordedValue);
        return new String(decValue);
    }
    
    private Key generateKey()
    {
        return new SecretKeySpec(keyValue, "AES");
    
    }
    
    /**
     * @param args the command line arguments
     
    public static void main(String[] args) {
        Settings settings = new SettingsImpl();
        try
        {
            //settings.saveToXML();
            
            //settings.loadFromXML();
            
            System.out.println(settings.getUsername());
            System.out.println(settings.getPassword());
        }catch(Exception ex){}
        Connector con = new ConnectorImpl();
        try
        {
            String str = con.getXMLFromURL("mhornak","projektPB138","kolo", "ssjc");
            XMLParser p = new XMLParserImpl();
            System.out.println(p.parseXML(str));
        }
        catch(Exception ex){System.out.println("exceptionMessage: " + ex.getMessage());
        }
        
    }*/
}
